package org.behrang.macbeans.tab;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Polygon;
import java.awt.Rectangle;
import javax.swing.Icon;
import javax.swing.JComponent;
import org.behrang.macbeans.Utils;
import org.netbeans.swing.tabcontrol.plaf.AbstractTabCellRenderer;
import org.netbeans.swing.tabcontrol.plaf.TabPainter;
import org.openide.awt.HtmlRenderer;

/**
 *
 * @author behrangsa
 */
public class BMEditorTabCellRenderer extends AbstractTabCellRenderer {

    public BMEditorTabCellRenderer() {
        super(new BMTabPainter(), new BMTabPainter(), new BMTabPainter(), new Dimension(23, 0));        
    }

    /**
     * Actually paints the icon and text (using the lightweight HTML renderer)
     *
     * @param g The graphics context
     */
    @Override
    protected void paintIconAndText(Graphics g) {
        g.setFont(getFont());
        FontMetrics fm = g.getFontMetrics(getFont());
        //Find out what height we need
        int txtH = fm.getHeight();
        Insets ins = getInsets();
        //find out the available height
        int availH = getHeight() - (ins.top + ins.bottom);
        int txtY;
        if (availH > txtH) {
            txtY = txtH + ins.top + ((availH / 2) - (txtH / 2)) - 3;
        } else {
            txtY = txtH + ins.top;
        }
        int txtX;

        int centeringToAdd = getPixelsToAddToSelection() != 0 ? getPixelsToAddToSelection() / 2 : 0;

        Icon icon = getIcon();
        //Check the icon non-null and height (see TabData.NO_ICON for why)
        if (!isClipLeft() && icon != null && icon.getIconWidth() > 0 && icon.getIconHeight() > 0) {
            int iconY;
            if (availH > icon.getIconHeight()) {
                //add 2 to make sure icon top pixels are not cut off by outline
                iconY = ins.top + ((availH / 2) - (icon.getIconHeight() / 2)) + 1;
            } else {
                //add 2 to make sure icon top pixels are not cut off by outline
                iconY = ins.top + 1;
            }
            int iconX = ins.left + centeringToAdd;

            iconY += getIconYAdjustment();

            icon.paintIcon(this, g, iconX, iconY);
            txtX = iconX + icon.getIconWidth() + getIconTextGap();
        } else {
            txtX = ins.left + centeringToAdd;
        }

        if (icon != null && icon.getIconWidth() == 0) {
            //Add some spacing so the text isn't flush for, e.g., the
            //welcome screen tab
            txtX += 5;
        }

        txtY += getCaptionYAdjustment();

        //Get the available horizontal pixels for text
        int txtW = getWidth() - (txtX + ins.right);
        if (isClipLeft()) {
            //fiddle with the string to get "...blah"
            String s = null; //preTruncateString(getText(), g, txtW - 4); //subtract 4 so it's not flush w/ tab edge

            HtmlRenderer.renderString(s, g, txtX, txtY, txtW, txtH, getFont(),
                    getForeground(), HtmlRenderer.STYLE_CLIP, true);
        } else {
            String s;
            if (isClipRight()) {
                //Jano wants to always show a "..." for cases where a tab is truncated,
                //even if we've really painted all the text.  
                s = getText() + "..."; //NOI18N

            } else {
                s = getText();
            }
            
            HtmlRenderer.renderString(s, g, txtX, txtY + 1, txtW, txtH, getFont(),
                    new Color(194, 194, 204), HtmlRenderer.STYLE_TRUNCATE, true);

            HtmlRenderer.renderString(s, g, txtX, txtY, txtW, txtH, getFont(),
                    getForeground(), HtmlRenderer.STYLE_TRUNCATE, true);
        }
    }

    private static class BMTabPainter implements TabPainter {

        private static Color COLOR_1 = new Color(174, 174, 174);
        private static Color COLOR_2 = new Color(64, 64, 64);
        private static Color COLOR_3 = new Color(59, 59, 59);
        private static Color COLOR_4 = new Color(120, 120, 120);
        private static Color COLOR_5 = new Color(153, 153, 153);
        private static Color COLOR_6 = new Color(140, 140, 140);

        public void getCloseButtonRectangle(JComponent c, Rectangle rect, Rectangle bounds) {
        }

        public Polygon getInteriorPolygon(Component c) {
            return new Polygon(
                    new int[]{0, c.getWidth(), c.getWidth(), 0},
                    new int[]{0, 0, c.getHeight(), c.getHeight()}, 4);
        }

        private void drawPixel(Graphics g, int x, int y) {
            g.drawLine(x, y, x, y);
        }
        private static Color C_1 = new Color(88, 88, 88);
        private static Color C_2 = new Color(89, 89, 89);
        private static Color C_3 = new Color(92, 92, 92);
        private static Color C_4 = new Color(96, 96, 96);
        private static Color C_5 = new Color(103, 103, 103);
        private static Color C_6 = new Color(113, 113, 113);
        private static Color C_7 = new Color(168, 168, 168);
        private static Color C_8 = new Color(88, 88, 88);
        private static Color C_9 = new Color(153, 153, 153);
        private static Color C_10 = new Color(64, 64, 64);
        // private static Color C_11 = new Color(150, 150, 150);
        private static Color C_11 = new Color(164, 164, 164);
        private static Color C_12 = new Color(147, 147, 147);
        private static Color C_13 = new Color(140, 140, 140);
        private static Color C_14 = new Color(134, 134, 134);
        private static Color C_15 = new Color(115, 115, 115);
        private static Color C_16 = new Color(98, 98, 98);

        private void drawSelectedTab(Graphics g, Component c) {
            final Rectangle r = c.getBounds();
            final int w = r.width - 1,  h = r.height;
            final Color old = g.getColor();

            // background
            g.setColor(C_11);
            g.fillRect(-1, 0, w + 2, h);

            // outer left
            int x0 = -1;
            int y0 = 1;
            g.setColor(C_1);
            g.drawLine(x0, y0, x0, h - 8);
            g.setColor(C_2);
            drawPixel(g, x0, h - 7);
            g.setColor(C_3);
            drawPixel(g, x0, h - 6);
            g.setColor(C_4);
            drawPixel(g, x0, h - 5);
            g.setColor(C_5);
            drawPixel(g, x0, h - 4);
            g.setColor(C_6);
            drawPixel(g, x0, h - 3);

            // inner left
            x0 = 0;
            g.setColor(C_12);
            drawPixel(g, x0, h - 7);
            g.setColor(C_13);
            drawPixel(g, x0, h - 6);
            g.setColor(C_14);
            drawPixel(g, x0, h - 5);
            g.setColor(C_15);
            drawPixel(g, x0, h - 4);
            g.setColor(C_16);
            drawPixel(g, x0, h - 3);

            // outer right
            x0 = w;
            y0 = 1;
            g.setColor(C_1);
            g.drawLine(x0, y0, x0, h - 8);
            g.setColor(C_2);
            drawPixel(g, x0, h - 7);
            g.setColor(C_3);
            drawPixel(g, x0, h - 6);
            g.setColor(C_4);
            drawPixel(g, x0, h - 5);
            g.setColor(C_5);
            drawPixel(g, x0, h - 4);
            g.setColor(C_6);
            drawPixel(g, x0, h - 3);

            // inner right
            x0 = w - 1;
            g.setColor(C_12);
            drawPixel(g, x0, h - 7);
            g.setColor(C_13);
            drawPixel(g, x0, h - 6);
            g.setColor(C_14);
            drawPixel(g, x0, h - 5);
            g.setColor(C_15);
            drawPixel(g, x0, h - 4);
            g.setColor(C_16);
            drawPixel(g, x0, h - 3);

            // bottom
            x0 = 1;
            y0 = h - 4;
            g.setColor(C_7);
            g.drawLine(x0, y0, w - 2, y0);
            y0 = h - 3;
            g.setColor(C_8);
            g.drawLine(x0, y0, w - 2, y0);

            x0 = -1;
            y0 = h - 2;
            g.setColor(C_9);
            g.drawLine(x0, y0, w, y0);
            y0 = h - 1;
            g.setColor(C_10);
            g.drawLine(x0, y0, w, y0);

            g.setColor(old);
        }
        
        public void paintInterior(Graphics g, Component c) {            
            final Rectangle r = c.getBounds();
            final int w = r.width - 1,  h = r.height;
            final BMEditorTabCellRenderer ren = (BMEditorTabCellRenderer) c;
            final Color old = g.getColor();
            
            // Utils.prints("Interior Bounds =", r);
            
            if (ren.isSelected()) {
                drawSelectedTab(g, c);
            } else {
                g.setColor(COLOR_4);
                g.fillRect(0, 0, w, h);

                g.setColor(COLOR_1);
                g.drawLine(0, 0, w - 1, 0);

                g.setColor(COLOR_2);
                g.drawLine(0, 1, w, 1);
                g.drawLine(0, h - 1, w, h - 1);

                if (!ren.isNextTabSelected()) {
                    g.setColor(COLOR_3);
                    g.drawLine(w , 1, w, h - 1);

                    g.setColor(COLOR_6);
                    g.drawLine(w - 1, 2, w - 1, h - 2);
                }
                
                g.setColor(COLOR_5);
                g.drawLine(0, h - 2, w - 1, h - 2);
            }

            g.setColor(old);
        }

        public boolean supportsCloseButton(JComponent c) {
            boolean leftClip = ((BMEditorTabCellRenderer) c).isClipLeft();
            boolean rightClip = ((BMEditorTabCellRenderer) c).isClipRight();
            boolean supported = ((BMEditorTabCellRenderer) c).isShowCloseButton();
            return !leftClip && !rightClip && supported;
        }

        public Insets getBorderInsets(Component c) {
            return new Insets(0, 0, 0, 0);
        }

        public boolean isBorderOpaque() {
            return true;
        }

        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            // Utils.prints("x =", x, "y =", y, "width =", width, "height =", height);
        }
    }
}
